package org.hoyi.web.ctrls;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.hoyi.DB.ctrl.Console;
import org.hoyi.DB.ents.Entity;
import org.hoyi.DB.model.DataRow;
import org.hoyi.DB.model.DataTable;
import org.hoyi.util.CutStrInfo;
import org.hoyi.util.Util;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

/**
 *          Author:ellen
 *          Email:ellen@kuaifish.com
 *          CreateDate:2015-05-20
 *          ModifyDate:2015-06-20
 *          hoyi entities @ hoyi.org
 *          使用请在项目关于内标注hoyi版权，
 *          hoyi版权归hoyi.org所有
 */
public class Repeater extends IHoyiCtrl
{
  public Boolean AutoGenerateColumn = Boolean.valueOf(false);
  public String HeaderTemplate;
  public String ItemTemplate;
  public String SeparatorTemplate;
  public String ItemTOFooter;
  public String FooterTemplate;
  public String NoneDataTemplate;
  
  String REPHEADER = "<hoyip:Repeater";
  String REPEND = "</hoyip:Repeater>";
  String HEADERTEMPLATE_HEADER = "<HeaderTemplate>";
  String HEADERTEMPLATE_END = "</HeaderTemplate>";
  String ITEMTEMPLATE_HEADER = "<ItemTemplate>";
  String ITEMTEMPLATE_END = "</ItemTemplate>";
  String SEPARATORTEMPLATE_HEADER = "<SeparatorTemplate>";
  String SEPARATORTEMPLATE_END = "</SeparatorTemplate>";
  String FOOTERTEMPLATE_HEADER = "<FooterTemplate>";
  String FOOTERTEMPLATE_END = "</FooterTemplate>";
  
  /**
   *  数据源个数为零时候的模板.
   */
  String NONEDATATEMPLATE_HEAD = "<NoneDataTemplate>";
  String NONEDATATEMPLATE_END = "</NoneDataTemplate>";
  
  String ItemTOFooter_HEADER = "<ItemTOFooter>";
  String ItemTOFooter_END = "</ItemTOFooter>";

  String PAGING_HEADER = "<Paging>";
  String PAGING_END = "</Paging>";
  String PagiCustom_HEADER = "<PagiCustom>";
  String PagiCustom_END = "</PagiCustom>";
  String PagiCurrent_HEADER = "<PagiCurrent>";
  String PagiCurrent_END = "</PagiCurrent>";
  
  public static String FooterStyle = "B";
  public static int pageNum = 10;

  public Repeater(String ctrid)
  {
    super(ctrid);
  }

  public Repeater(String ctrid, IHoyiCtrl parent)
  {
    super(ctrid, parent);
  }

  public String getId()
  {
    return super.getId();
  }

  public void setId(String id)
  {
    super.setId(id);
  }

  public String InitContentByTemplates(String _template)
  {
    String repHeader = this.REPHEADER + " Id=\"" + getId() + "\"";

    CutStrInfo strInfo = new CutStrInfo(repHeader, this.REPEND);
    boolean contain = strInfo.Calc(_template);
    if (contain) {
      setHtmlContent(strInfo.getEXPREDContent());
      this.rendedHTMLContent = strInfo.getEXPREDContent();
      CutStrInfo headerInfo = new CutStrInfo(this.HEADERTEMPLATE_HEADER, this.HEADERTEMPLATE_END, getHtmlContent());
      CutStrInfo itemInfo = new CutStrInfo(this.ITEMTEMPLATE_HEADER, this.ITEMTEMPLATE_END, getHtmlContent());
      CutStrInfo item2footinfo = new CutStrInfo(this.ItemTOFooter_HEADER, this.ItemTOFooter_END, getHtmlContent());
      CutStrInfo footinfo = new CutStrInfo(this.FOOTERTEMPLATE_HEADER, this.FOOTERTEMPLATE_END, getHtmlContent());
      CutStrInfo nonedatainfo = new CutStrInfo(this.NONEDATATEMPLATE_HEAD, this.NONEDATATEMPLATE_END, getHtmlContent());
      
      headerInfo.Calc(false);
      itemInfo.Calc(false);
      item2footinfo.Calc(false);
      footinfo.Calc(false);
      nonedatainfo.Calc(false);

      this.HeaderTemplate = headerInfo.getEXPREDContent();
      this.ItemTemplate = itemInfo.getEXPREDContent();
      this.ItemTOFooter = item2footinfo.getEXPREDContent();
      this.FooterTemplate = footinfo.getEXPREDContent();
      this.NoneDataTemplate = nonedatainfo.getEXPREDContent();
      
      Console.Info("HeaderTemplate:" + this.HeaderTemplate);
      Console.Info("ItemTemplate:" + this.ItemTemplate);
      Console.Info("ItemTOFooter:" + this.ItemTOFooter);
      Console.Info("FooterTemplate:" + this.FooterTemplate);
      Console.Info("NoneDataTemplate:" + this.NoneDataTemplate);
    }
    return this.HtmlContent;
  }

  public boolean ContainMethod(Method[] method, String methodName) {
    for (Method md : method) {
      if (md.getName().equals(methodName)) {
        return true;
      }
    }
    return false;
  }

  public String Render()
  {
    return RenderT(this.HtmlContent);
  }

  public String RenderT(String Template)
  {
    String neirong = "";

    if (this.EntitySource != null) {
      for (Iterator localIterator = this.EntitySource.iterator(); localIterator.hasNext(); ) { Object ent = localIterator.next();

      	String subcon = TransSubTemplate(ItemTemplate, ent, 0);
      	
        neirong = neirong + TransEnts(subcon, (Entity)ent, "");
      }
    }
    Object tmpobj = null;
    if (this.TableSource != null) {
      for (int i = 0; i < this.TableSource.RowsCount(); i++) {
    	  String subcon =  TransSubTemplate(ItemTemplate, this.TableSource.getRow(i), 0);
        neirong = neirong + TransField(subcon, this.TableSource.getRow(i), i, "");
      }
    }
    
    if(this.JsonSource != null) {
    	for (int i = 0; i < JsonSource.size(); i++) {
          	String subcon = TransSubTemplate(ItemTemplate, JsonSource.getJSONObject(i), 0);
    		neirong = neirong + TransJSONField(subcon, JsonSource.getJSONObject(i), i, "");
		}
    }

    String Footer = ""; String Header = "";
    if (this.FooterTemplate != null) {
      Footer = TransFooter(this.FooterTemplate);
    }
    if (this.HeaderTemplate != null) {
      Header = this.HeaderTemplate;
    }

    this.rendedHTMLContent = (Header + neirong + ItemTOFooter + Footer);
    this.rendedHTMLContent = TransEXCUTEMethod(this.rendedHTMLContent);
    
    if ((this.EntitySource == null ||(this.EntitySource != null && this.EntitySource.size() <= 0)) && (this.TableSource == null ||(this.TableSource != null && this.TableSource.RowsCount() <= 0)) && (this.JsonSource == null ||(this.JsonSource != null && this.JsonSource.size() <= 0))) {
    	this.rendedHTMLContent = NoneDataTemplate;
	}
    
    return this.rendedHTMLContent;
  }

  public String TransFooter(String _template)
  {
    if ((_template != null) && (getDataCount() > 0)) {
      CutStrInfo pagi = new CutStrInfo(this.PAGING_HEADER, this.PAGING_END, _template);
      boolean contain = pagi.Calc(false);
      if (contain)
      {
        String cureentstr = ""; String resultStr = ""; String pagingStr = "";
        CutStrInfo custom = new CutStrInfo(this.PagiCustom_HEADER, this.PagiCustom_END, pagi.getEXPREDContent());
        custom.Calc(false);
        CutStrInfo current = new CutStrInfo(this.PagiCurrent_HEADER, this.PagiCurrent_END, pagi.getEXPREDContent());
        current.Calc(false);
        CalcPageCount(this.DataCount, getPageSize());

        switch (Repeater.FooterStyle) {
			case "A":
			       for (int i = 0; i < getPageCount(); i++) {
	//		         for (int i = 0; i < 10; i++) {
	//		         for(int i = this.PageIndex + 5; i< this.PageCount - this.PageIndex + 5; i ++){
			           if (i + 1 == this.PageIndex)
			             cureentstr = cureentstr + current.getEXPREDContent().replace("{# pageindex #}", String.valueOf(i + 1));
			           else {
			             cureentstr = cureentstr + custom.getEXPREDContent().replace("{# pageindex #}", String.valueOf(i + 1));
			           }
	
			         }
				break;
			case "B":
				
				int pgIndex = this.PageIndex;
				int pgCount =  getPageCount();
				if(pgCount > pageNum){
					int halfPage = (int)Math.floor(pageNum / 2.0);
					if(pgIndex > halfPage){//不做处理
						pgCount = pgIndex + halfPage;
						if(pgCount > getPageCount()){
							pgCount = getPageCount();
							if(pgIndex > pgCount - halfPage){
								pgIndex = pgCount - pageNum + 1;
							}
						}else{
							pgIndex = pgIndex - halfPage;
						}
						
					}else{
						pgCount = pageNum;
						pgIndex = 1;
					}
				}else{
					pgIndex = 1;
				}
	//		         for (int i = 0; i < 10; i++) {
				for(int i = pgIndex - 1; i< pgCount; i ++){
			           if (i + 1 == this.PageIndex)
			             cureentstr = cureentstr + current.getEXPREDContent().replace("{# pageindex #}", String.valueOf(i + 1));
			           else {
			             cureentstr = cureentstr + custom.getEXPREDContent().replace("{# pageindex #}", String.valueOf(i + 1));
			           }
	
			         }
				break;
			case "C":
				break;
		default:
			  for (int i = 0; i < getPageCount(); i++) {
					//		         for (int i = 0; i < 10; i++) {
					//		         for(int i = this.PageIndex + 5; i< this.PageCount - this.PageIndex + 5; i ++){
							           if (i + 1 == this.PageIndex)
							             cureentstr = cureentstr + current.getEXPREDContent().replace("{# pageindex #}", String.valueOf(i + 1));
							           else {
							             cureentstr = cureentstr + custom.getEXPREDContent().replace("{# pageindex #}", String.valueOf(i + 1));
							           }
					
							         }
			break;
		}
 

        pagingStr = _template.replace(this.PAGING_HEADER + pagi.getEXPREDContent() + this.PAGING_END, cureentstr);

        resultStr = pagingStr.replace("{# pagecount #}", String.valueOf(getPageCount()));

        return resultStr;
      }
    }
    Console.Info("Template is NULL");

    return "";
  }
  /**
   * 替换DataRow内容。
   * @param Template
   * @param dr
   * @param j
   * @param wclass，伪类，用于子模板，例如:website.websitename, 子模板请加.否则置空
   * @return
   */
  public String TransField(String Template, DataRow dr, int j, String wclass)
  {
    if ((Template == null) || (Template == "")) {
     Console.Info("TransField  Template is NULL");
      return Template;
    }

    //Template = TransSubTemplate(Template,dr, 0);
    for (int i = 0; i < dr.getColumns().size(); i++) {
      String FieldName = dr.getColumn(i).ColumnName;
      String value = dr.GetData(i) != null ? dr.GetData(i).toString() : "";

      Template = Template.replace("{# " + wclass + FieldName + " #}", value);
    }
    Template = transItemCondi(Template, null, dr, null, "datatable", 0);
    Template = TransEXCUTEMethod(Template);
    return Template;
  }
  /**
   * 解析JSON字段
   * @param Template
   * @param obj
   * @param j
   * @param wclass,伪类，如:website.websiteid.
   * @return
   */
  public String TransJSONField(String Template, JSONObject obj, int j, String wclass)
  {
    if ((Template == null) || (Template == "")) {
    	Console.Info("TransField  Template is NULL");
      return Template;
    }
    //Template = TransSubTemplate(Template,obj, 0);
    Iterator<String> it = obj.keys();
    while (it.hasNext()) {
    	// 获得key
    	String FieldName = it.next(); 
    	String value = obj.getString(FieldName);  
    	
    	Template = Template.replace("{# " + wclass + FieldName + " #}", value);
		
	}
    Template = transItemCondi(Template, null, null, obj, "json", 0);
    Template = TransEXCUTEMethod(Template);
    return Template;
  }
  /**
   * 替换实体内容
   * @param Template
   * @param ent
   * @param wclass 伪类，用于子模板，PS: site.sitename,无内容，请置空,有则不能少.
   * @return
   */
  public String TransEnts(String Template, Entity ent, String wclass) {
    if ((Template == null) || (Template == "")) {
      Console.Info("TransEnts  Template is NULL");
      return Template;
    }
    //Template = TransSubTemplate(Template, ent, 0);

    Field[] fields = ent.getClass().getDeclaredFields();

    for (Field field : fields) {
      Method[] method = ent.getClass().getMethods();
      for (Method md : method) {
        if (md.getName().equals("get" + Util.FirstUpToParscal(field.getName()))) {
          try
          {
            Object objtmp = md.invoke(ent, new Object[0]);

            if (objtmp != null) {
              String objtmp2 = objtmp.toString();
              String valifield = "{# "  + wclass + field.getName() + " #}";
              Template = Template.replace(valifield, objtmp2);
            }

          }
          catch (IllegalAccessException|IllegalArgumentException|InvocationTargetException e)
          {
          	Console.Error(e);
          }
        }
      }
    }
    
//    Template = transItemCondi(Template, ent, 0);
    Template = transItemCondi(Template, ent, null, null, "entity", 0);
    
    Template = TransEXCUTEMethod(Template);
    return Template;
  }

  /**
   * 是否包含可以操作的条件.
   * @param itemTemplate
   * @param fromidx
   * @return
   */
  public boolean CanTransCondi(String itemTemplate, int fromidx) {
	  String starcondtag = "<condi";
	  String endcondtag = "</condi>";
	  
	  int staridx = itemTemplate.indexOf(starcondtag, fromidx);
	  int endidx = itemTemplate.indexOf(endcondtag, fromidx);
	  
//	  if(endidx > staridx)// 存在可用的条件.
	  return endidx > 0 && staridx > 0 && endidx > staridx;
  }
  /**
   * 获取Condi 中间的内容，因为getText和((Element)elm).asXML();两个一个只能获取文本内容，一个只能获取xml内容。
   * 所以在这里condi标签的头和尾删掉就成了中间的内容.
   */
  public String GetCondiContent(String condicontent) {
		String content = "";
		try {
			// 拿到第一個關閉的Tag.
			int firstClose = condicontent.indexOf('>');
//			String startTag = condicontent.substring(0, firstClose);
			String endTag = "</condi>";
			int endTagidx = condicontent.indexOf(endTag);
			
			content = condicontent.substring(firstClose + 1, endTagidx);
		} catch (Exception e) {
		}
		
		return content;
  }
  /**
   * 将formula 的值取出来，避免用xml转换的时候报错。
   * 
   * <condi attr="status" formula="=" value="0">
                  <div class="prod_cover">&nbsp;</div>
                  <div class="prod_cover_txt">未开拍</div>
                </condi>
   * @param formulas
   * @return
   */
//  public Map<String, String> GetFormuValues(String formulas){
//	  Map<String, String> values = new HashMap<String, String>();
//	  String starcondtag = "<condi";
//	  int staridx = formulas.indexOf(starcondtag, 0);
//	  int endidx = formulas.indexOf(">", 1);
//	  if (staridx >= 0 && endidx > 1) {
//		 String formuv = formulas.substring(staridx, endidx);
//		 
//	  }
//	  
//	  values.put("attr", "");
//	  values.put("formula", "");
//	  values.put("value", "");
//	  return values;
//  }
  /**
   * 替换条件公式.
   * @param itemTemplate
   * @param fromidx
   * @return
   */
  public String transItemCondi(String itemTemplate, Entity ent, DataRow dr, JSONObject jobt, String srctype, int fromidx) {
	  while (CanTransCondi(itemTemplate, fromidx)) {
		  String starcondtag = "<condi";
		  String endcondtag = "</condi>";
		  
		  int staridx = itemTemplate.indexOf(starcondtag, fromidx);
		  int endidx = itemTemplate.indexOf(endcondtag, fromidx);
		  String condi = itemTemplate.substring(staridx, endidx + endcondtag.length());
		  String condicontent = condi;
		  Document document;
			try {
				document = DocumentHelper.parseText(condicontent);
		    	// formula 支持, = ,<, <=, >, >=, <>, in, contain
		    	// formula 支持, !=, !<, !<=, !>, !>=, !<>, !in, !contain, 加上!表明trim()之后的判断，暂不提供.
				// attr = value , attr contain value 类似这种比较，true,则把替换，否则替换成null.
				Attribute atat = document.getRootElement().attribute("attr");
				Attribute atfo = document.getRootElement().attribute("formula");
				Attribute atva = document.getRootElement().attribute("value");
				if(atat == null || atfo == null || atva == null){
//		    		itemTemplate = itemTemplate.replace(condi, ""); 
		    		return itemTemplate;
				}
				String attr = atat.getValue();
		    	String formula = atfo.getValue();
		    	String value = atva.getValue();
				
//				Map<String, String> formuvalues = GetFormuValues(condicontent);
//		    	String attr = formuvalues.get("attr");
//		    	String formula = formuvalues.get("formula");
//		    	String value = formuvalues.get("value");
		    	
		    	Object objtmp = null;
		    	if(srctype.equals("entity")) {
		    		String mthname = "get" + Util.FirstUpToParscal(attr);
		    		Method md = ent.getClass().getMethod(mthname);
		    		objtmp = md.invoke(ent, new Object[0]);
		    		String nodeName = "condi";
		    	}else if(srctype.equals("datatable")) {
		    		objtmp = dr.GetData(attr);
		    	}else if(srctype.equals("json")) {
		    		objtmp = jobt.get(attr);
		    	}
		    	if(objtmp == null) {
		    		itemTemplate = itemTemplate.replace(condi, ""); 
		    		return itemTemplate;
		    	}
	    		
		    	if(formula.equals("contain")) {// 这个是字符串比较。
		            if (objtmp != null) {
			            String objtmp2 = objtmp.toString();
			            if(objtmp2.contains(value)){// 条件满足.
			            	String conditext = "";
			            	
//			    			for (Object elm : document.getRootElement().elements()) {
//			    				conditext += ((Element)elm).asXML();
//							}
//			    			conditext = document.getRootElement().getText();
			            	conditext = GetCondiContent(condicontent);
				            itemTemplate = itemTemplate.replace(condi, conditext); 
			            }else {
				            itemTemplate = itemTemplate.replace(condi, ""); 
			            }
		            }
		    	}else {// 这个是公式比较.
//		    		int attrs = Integer.parseInt(objtmp.toString());
//		    		int valueint = Integer.parseInt(value);
		    		boolean ret = false;
		    		if(formula.equals("=")) {
		    			if(objtmp instanceof Integer) {
		    				ret = (Integer.parseInt(objtmp.toString()) == Integer.parseInt(value));
		    			}else if(objtmp instanceof Double) {
		    				ret = (Double.parseDouble(objtmp.toString()) == Double.parseDouble(value));
		    			}else if(objtmp instanceof Float) {
		    				ret = (Float.parseFloat(objtmp.toString()) == Float.parseFloat(value));
		    			}else {
			    			ret = objtmp.equals(value);
		    			}
		    		}
		    		if(formula.equals(">")) {
		    			if(objtmp instanceof Integer) {
		    				ret = (Integer.parseInt(objtmp.toString()) > Integer.parseInt(value));
		    			}else if(objtmp instanceof Double) {
		    				ret = (Double.parseDouble(objtmp.toString()) > Double.parseDouble(value));
		    			}else if(objtmp instanceof Float) {
		    				ret = (Float.parseFloat(objtmp.toString()) > Float.parseFloat(value));
		    			}else {
		    				ret = (Double.parseDouble(objtmp.toString()) > Double.parseDouble(value));
						}
		    		}
		    		if(formula.equals(">=")) {
		    			if(objtmp instanceof Integer) {
		    				ret = (Integer.parseInt(objtmp.toString()) >= Integer.parseInt(value));
		    			}else if(objtmp instanceof Double) {
		    				ret = (Double.parseDouble(objtmp.toString()) >= Double.parseDouble(value));
		    			}else if(objtmp instanceof Float) {
		    				ret = (Float.parseFloat(objtmp.toString()) >= Float.parseFloat(value));
		    			}else {
		    				ret = (Double.parseDouble(objtmp.toString()) >= Double.parseDouble(value));
						}
		    		}
		    		if(formula.equals("<")) {
		    			if(objtmp instanceof Integer) {
		    				ret = (Integer.parseInt(objtmp.toString()) < Integer.parseInt(value));
		    			}else if(objtmp instanceof Double) {
		    				ret = (Double.parseDouble(objtmp.toString()) < Double.parseDouble(value));
		    			}else if(objtmp instanceof Float) {
		    				ret = (Float.parseFloat(objtmp.toString()) < Float.parseFloat(value));
		    			}else {
		    				ret = (Double.parseDouble(objtmp.toString()) < Double.parseDouble(value));
						}
		    		}
		    		if(formula.equals("<=")) {
		    			if(objtmp instanceof Integer) {
		    				ret = (Integer.parseInt(objtmp.toString()) <= Integer.parseInt(value));
		    			}else if(objtmp instanceof Double) {
		    				ret = (Double.parseDouble(objtmp.toString()) <= Double.parseDouble(value));
		    			}else if(objtmp instanceof Float) {
		    				ret = (Float.parseFloat(objtmp.toString()) <= Float.parseFloat(value));
		    			}else {
		    				ret = (Double.parseDouble(objtmp.toString()) <= Double.parseDouble(value));
						}
		    		}

		    		if(formula.equals("<>")) {
		    			if(objtmp instanceof Integer) {
		    				ret = (Integer.parseInt(objtmp.toString()) != Integer.parseInt(value));
		    			}else if(objtmp instanceof Double) {
		    				ret = (Double.parseDouble(objtmp.toString()) != Double.parseDouble(value));
		    			}else if(objtmp instanceof Float) {
		    				ret = (Float.parseFloat(objtmp.toString()) != Float.parseFloat(value));
		    			}else {
		    				ret = (Double.parseDouble(objtmp.toString()) != Double.parseDouble(value));
						}
		    		}

		    		if(formula.equals("noequals")) {
		    			if(objtmp instanceof Integer) {
		    				ret = (Integer.parseInt(objtmp.toString()) != Integer.parseInt(value));
		    			}else if(objtmp instanceof Double) {
		    				ret = (Double.parseDouble(objtmp.toString()) != Double.parseDouble(value));
		    			}else if(objtmp instanceof Float) {
		    				ret = (Float.parseFloat(objtmp.toString()) != Float.parseFloat(value));
		    			}else {
		    				ret = (!objtmp.equals(value));
						}
		    		}
		    		if(formula.equals("notnull")) {
		    			ret = objtmp!= null && (objtmp + "").length() > 0;
		    		}

		    		if(formula.equals("null")) {
		    			ret = objtmp!= null || (objtmp + "").length() == 0;
		    		}
		    		
		    		if(ret) {
		    			String conditext = "";
		    			
//		    			for (Object elm : document.getRootElement().elements()) {
//		    				conditext += ((Element)elm).asXML();
//						}
//		    			conditext = document.getRootElement().getText();
		    			conditext = GetCondiContent(condicontent);
		    			itemTemplate = itemTemplate.replace(condi, conditext); 
		    		}else {
			            itemTemplate = itemTemplate.replace(condi, ""); 
		            }
		    	}
			} catch (DocumentException | NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
				Console.Info("Condi Trans Error:" + e.getMessage());
	            itemTemplate = itemTemplate.replace(condi, ""); 
			} 
//	    	fromidx= endidx + endcondtag.length() -1;
	    	fromidx = 0;
	  }
	  
	  return itemTemplate;
  }
  /**
   * 获取根目录的XML,去掉根目录
   * @param document
   * @return
   */
  String GetRootXML(Document document) {
	  String conditext = "";
	for (Object elm : document.getRootElement().elements()) {
		conditext += ((Element)elm).asXML();
	}
	return conditext;
  }
  /**
   * 是否有子模板可操作
   * @param itemTemplate
   * @param fromidx
   * @return
   */
  public boolean CanTransSubTemplate(String itemTemplate, int fromidx) {
	  if(StringUtils.isBlank(itemTemplate)) {
		  return false;
	  }
	  String starcondtag = "<SubTemplate";
	  String endcondtag = "</SubTemplate>";
	  
	  int staridx = itemTemplate.indexOf(starcondtag, fromidx);
	  int endidx = itemTemplate.indexOf(endcondtag, fromidx);
	  
//	  if(endidx > staridx)// 存在可用的条件.
	  return endidx > 0 && staridx > 0 && endidx > staridx;
  }
  /**
   * 解析SubTemplate.
   * @param itemTemplate
   * @param datasrc
   * @param fromidx
   * @return
   */
  public String TransSubTemplate(String template, Object datasrc, int fromidx) {
	  while (CanTransSubTemplate(template, fromidx)) {
		  String starcondtag = "<SubTemplate";
		  String endcondtag = "</SubTemplate>";
		  
		  int staridx = template.indexOf(starcondtag, fromidx);
		  int endidx = template.indexOf(endcondtag, fromidx);
		  String condi = template.substring(staridx, endidx + endcondtag.length());
		  String condicontent = condi;
		  
	    	Document document;
			try {
				document = DocumentHelper.parseText(condicontent);
				condicontent = GetRootXML(document);
				
		    	String attr = document.getRootElement().attribute("attr").getValue(); // 伪字段名，用于标识主表不同内容.
		    	String src = document.getRootElement().attribute("src").getValue();// 字段名
		    	
		    	Object usingdatasrc = null;
		    	
		    	if(datasrc instanceof DataRow) {// 如果数据源是List
		    		DataRow cutable = (DataRow) datasrc;
		    		usingdatasrc = cutable.GetData(src);
		    	}else if(datasrc instanceof JSONObject) {
		    		usingdatasrc = ((JSONObject)datasrc).get(src);
		    	}else {// if(datasrc instanceof List<Entity>) { Entity
		    		String mthname = "get" + Util.FirstUpToParscal(attr);
		    		Entity ent = (Entity)datasrc;
		    		Method md = ent.getClass().getMethod(mthname);
		    		usingdatasrc = md.invoke(ent, new Object[0]);
		    	}
		    	if(usingdatasrc != null) {

			    	String subtcond  = TransSimpSubTemp(condicontent, usingdatasrc, attr);
//			    	String conditext = GetRootXML(document);
			    	template = template.replace(condi, subtcond);
		    	}else {
		    		template = template.replace(condi, "<p>Sub Temp Error,Check Pls.</p>");
		    	}
			} catch (DocumentException  | SecurityException  | IllegalArgumentException | NoSuchMethodException | IllegalAccessException | InvocationTargetException  e) {
				Console.Error("Condi Trans Error:" + e.getMessage());
				template = template.replace(condi, ""); 
			} 
//	    	fromidx= endidx + endcondtag.length() -1;
	    	fromidx = 0;
	  }
	  
	  return template;
  }
  /**
   * 替换子模版
   * @param subtemp
   * @param usingdatasrc
   * @param attr 伪类提供.
   * @return
   */
  public String TransSimpSubTemp(String subtemp, Object usingdatasrc, String attr) {
	  String subcontent="";
	  if(usingdatasrc instanceof DataTable) {
		  DataTable tsrc = (DataTable) usingdatasrc;
	      for (int i = 0; i < tsrc.RowsCount(); i++) {
	    	  subcontent = subcontent + TransField(subtemp, tsrc.getRow(i), i, attr + ".");
	      }
	  }else if(usingdatasrc instanceof JSONArray) {
		  JSONArray jrc = (JSONArray)usingdatasrc;
		  for (int i = 0; i < jrc.size(); i++) {
			  subcontent = subcontent + TransJSONField(subtemp, jrc.getJSONObject(i), i, attr + ".");
		  }
	  }else {// 当List<Entity>来用，暂不接受其他类型的数据源.
		  List<Entity> dataentity = (List<Entity>)usingdatasrc;
		  for (Iterator localIterator = dataentity.iterator(); localIterator.hasNext(); ) {
			  Object ent = localIterator.next();
			  subcontent = subcontent + TransEnts(subtemp, (Entity)ent, attr + ".");
	      }
	  }
	  return subcontent;
  }
}

